﻿//////////////////////////////////////////////////
//                Gladiator.cs                  //
//         Part of RebornCo by kaihaider        //
//////////////////////////////////////////////////

using System.Linq;
using System.Threading.Tasks;
using ff14bot;
using ff14bot.Enums;
using RebornCo.Helpers;
using RebornCo.Settings;
using TreeSharp;

namespace RebornCo.Rotations
{
    public class Gladiator : RebornCoRoutine
    {
        public override void OnInitialize()
        {
            WantHealing = false;
            WindowSettings = new GladiatorSetting();
        }
        public static GladiatorSetting GladiatorSettings
        {
            get { return WindowSettings as GladiatorSetting; }
        }
        public sealed override ClassJobType[] Class
        {
            get
            {
                return new [] 
                { 
                   ClassJobType.Gladiator, ClassJobType.Paladin
                };
            }
        }
        [Behavior(BehaviorType.PreCombatBuffs)]
        public Composite GladiatorCreateBasicPreCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => GladiatorBuildPreCombatBuffs());
        }
        public static async Task<bool> GladiatorBuildPreCombatBuffs()
        {
            if (!IsValid()) return false;
            if (await Spell.CastLock("Sword Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Sword
                || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent > GladiatorSettings.OathAutoHealthPercentage
                || GladiatorSettings.Oath == PallyOaths.Rotation && !Spell.RotationSwap) && !Core.Player.HasAura("Sword Oath")))
                return true;
            if (await Spell.CastLock("Shield Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Shield
                || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent < GladiatorSettings.OathAutoHealthPercentage
                || GladiatorSettings.Oath == PallyOaths.Rotation && Spell.RotationSwap) && !Core.Player.HasAura("Shield Oath")))
                return true;
            if (Resting)
            {
                if (!Core.Player.IsCasting && await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                if (!Core.Player.IsCasting && await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 70 && Core.Player.CurrentHealthPercent < Core.Player.CurrentManaPercent)) return true;
                return false;
            } 
            if (await Spell.BuffParty("Protect")) return true;
            if (await Spell.BuffParty("Stoneskin")) return true;
            return await CombatCompanion();
        }
        [Behavior(BehaviorType.Rest)]
        public Composite GladiatorCreateBasicRest()
        {
            return new ActionRunCoroutine(ctx => DefaultRestBehavior(Core.Player.CurrentTPPercent)); 
        }
        [Behavior(BehaviorType.CombatBuffs)]
        public Composite GladiatorCreateBasicCombatBuffs()
        {
            return new ActionRunCoroutine(ctx => GladiatorBuildCombatBuffs()); 
        }
        public static async Task<bool> GladiatorBuildCombatBuffs()
        {
            ShouldPulse = true;
            //add cover
            if (await Spell.Cast("Cure", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (await Spell.Cast("Physick", Core.Player, Core.Player.CurrentHealthPercent < 40)) return true;
            if (Spell.GcdTime < GladiatorSettings.NoneGcdWindowEnd) return false;
            //flash if you need aoe aggro, Provoke single target
            //Tempered Will check for blind or heavy
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Sword Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Sword
                || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent > GladiatorSettings.OathAutoHealthPercentage
                || GladiatorSettings.Oath == PallyOaths.Rotation && !Spell.RotationSwap) && !Core.Player.HasAura("Sword Oath")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Shield Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Shield
                || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent < GladiatorSettings.OathAutoHealthPercentage
                || GladiatorSettings.Oath == PallyOaths.Rotation && Spell.RotationSwap) && !Core.Player.HasAura("Shield Oath")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Hallowed Ground", Core.Player, Core.Player.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Bulwark", Core.Player, Core.Player.CurrentHealthPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Sentinel", Core.Player, Core.Player.CurrentHealthPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Awareness", Core.Player, Core.Player.CurrentHealthPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Convalescence", Core.Player, Core.Player.CurrentHealthPercent < 50))
            {//increases healing recieved
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Fight or Flight", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Rampart", Core.Player, Core.Player.CurrentHealthPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }

            if (!Spell.UsedNoneGcd && await Spell.CastLock("Invigorate", Core.Player, Core.Player.CurrentTPPercent < 50))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Eye for an Eye", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Blood for Blood", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Internal Release", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (WindowSettings.CooldownsUsable && Spell.Potion != null && Spell.Potion.IsValid
                && Spell.Potion.CanUse(Core.Player) && Spell.Potion.Name.Equals(WindowSettings.PotionName))
            {
                Spell.Potion.UseItem(Core.Player);
                if (WindowSettings.PotionForce) Spell.UsedNoneGcd = true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Quelling Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Hawk's Eye", Core.Player))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Bloodbath", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Raging Strikes", Core.Player, true))
            {
                Spell.UsedNoneGcd = true;
                return true;
            } 
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Keen Flurry", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Foresight", Core.Player, Core.Player.CurrentHealthPercent < 80))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Convalescence", Core.Player, Core.Player.CurrentHealthPercent < 70))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Second Wind", Core.Player, Core.Player.CurrentHealthPercent < 40))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Awareness", Core.Player, Core.Player.CurrentHealthPercent < 30))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Featherfoot", Core.Player, Core.Player.Distance2D() < 5))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            return false;
        }
        [Behavior(BehaviorType.Pull)]
        public Composite GladiatorCreateBasicPull()
        {
            return new ActionRunCoroutine(ctx => GladiatorBuildPullBehavior()); 
        }
        public static async Task<bool> GladiatorBuildPullBehavior()
        {
            if (Core.Player.CurrentTarget != null && !Core.Player.CurrentTarget.CanAttack || !IsValid()) return false;
            ShouldPulse = true;
            await Target.EnsureValidTarget();
            if (await Movement.PullMove(Core.Player.CurrentTarget)) return true;
            if (!Spell.Gcd && (Spell.RotationSwap || GladiatorSettings.RageDuringOffTank) && Spell.LastCombo == Combo.SavageBlade && Core.Player.CurrentTarget != null && Core.Player.ClassLevel > 25)
            {
                return await Spell.PullCast("Rage of Halone", Core.Player.CurrentTarget, true);
            }
            if (!Spell.Gcd && Spell.LastCombo == Combo.FastBlade && Core.Player.CurrentTarget != null && Core.Player.ClassLevel > 3)
            {
                if (await Spell.PullCast("Riot Blade", Core.Player.CurrentTarget, Core.Player.ClassLevel > 11
                  && (Spell.CachedCombo == Combo.RiotBlade || Spell.CachedCombo == Combo.Flushed
                  && Core.Player.CurrentManaPercent < 30))) return true;
                return await Spell.PullCast("Savage Blade", Core.Player.CurrentTarget,
                    (Spell.CachedCombo == Combo.Flushed || Spell.CachedCombo == Combo.SavageBlade));
            }
            if (await Spell.PullCast("Fast Blade", Core.Player.CurrentTarget)) return true;

            return false;
        }

        [Behavior(BehaviorType.Combat)]
        public Composite GladiatorCreateBasicCombat()
        {
            return new ActionRunCoroutine(ctx => GladiatorBuildBasicCombat()); 
        }
        public static async Task<bool> GladiatorBuildBasicCombat()
        {
            await Target.EnsureValidTarget();
            await Movement.MoveToTarget(); 
            if (Core.Player.CurrentTarget != null && ff14bot.Managers.MovementManager.IsMoving
                && !(Core.Player.CurrentTarget.InLineOfSight() && Core.Player.CurrentTarget.Distance2D() < Movement.ObjectMeleeRange(Core.Player.CurrentTarget))) return true;
            if (!Spell.Gcd && (Spell.RotationSwap || GladiatorSettings.RageDuringOffTank) && Spell.LastCombo == Combo.SavageBlade && Core.Player.CurrentTarget != null && Core.Player.ClassLevel > 25)
            {
                return await Spell.Cast("Rage of Halone", Core.Player.CurrentTarget, true);
            }
            if (!Spell.Gcd && Spell.LastCombo == Combo.FastBlade && Core.Player.CurrentTarget != null && Core.Player.ClassLevel > 3)
            {
                if (await Spell.Cast("Riot Blade", Core.Player.CurrentTarget, Core.Player.ClassLevel > 11
                  && (Spell.CachedCombo == Combo.RiotBlade || Spell.CachedCombo == Combo.Flushed
                  && Core.Player.CurrentManaPercent < 30))) return true;
                return await Spell.Cast("Savage Blade", Core.Player.CurrentTarget,  
                    (Spell.CachedCombo == Combo.Flushed || Spell.CachedCombo == Combo.SavageBlade));
            }
            //Shield Swipe
            if (!Spell.Gcd && await Spell.CastLock("Shield Lob", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null 
                && 15 > Core.Player.CurrentTarget.Distance2D()
                && Core.Player.CurrentTarget.Distance2D() > Movement.MeleeRange + 5)) return true;
            if (!Spell.Gcd && await Spell.Cast("Circle of Scorn", Core.Player.CurrentTarget, GladiatorSettings.Aoe && Target.mNearbyEnemyUnits() != null && Target.mNearbyEnemyUnits().Count(unit => unit.Distance2D() <= 5) >= GladiatorSettings.AoeCount)) return true;
            if (!Spell.Gcd && await Spell.Cast("Fast Blade", Core.Player.CurrentTarget)) return true;

            if ((Spell.GcdTime > GladiatorSettings.NoneGcdWindowEnd || Core.Player.CurrentTarget != null 
                && !(Core.Player.CurrentTarget.InLineOfSight() && Core.Player.CurrentTarget.Distance2D() < Movement.ObjectMeleeRange(Core.Player.CurrentTarget))) 
                && await Spell.CastLock("Sword Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Sword
    || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent > GladiatorSettings.OathAutoHealthPercentage
    || GladiatorSettings.Oath == PallyOaths.Rotation && !Spell.RotationSwap) && !Core.Player.HasAura("Sword Oath")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if ((Spell.GcdTime > GladiatorSettings.NoneGcdWindowEnd || Core.Player.CurrentTarget != null
                && !(Core.Player.CurrentTarget.InLineOfSight() && Core.Player.CurrentTarget.Distance2D() < Movement.ObjectMeleeRange(Core.Player.CurrentTarget))) 
                && await Spell.CastLock("Shield Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Shield
                || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent < GladiatorSettings.OathAutoHealthPercentage
                || GladiatorSettings.Oath == PallyOaths.Rotation && Spell.RotationSwap) && !Core.Player.HasAura("Shield Oath")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (Spell.GcdTime < GladiatorSettings.NoneGcdWindowEnd) return false;
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Sword Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Sword
    || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent > GladiatorSettings.OathAutoHealthPercentage
    || GladiatorSettings.Oath == PallyOaths.Rotation && !Spell.RotationSwap) && !Core.Player.HasAura("Sword Oath")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Shield Oath", Core.Player, (GladiatorSettings.Oath == PallyOaths.Shield
                || GladiatorSettings.Oath == PallyOaths.Auto && Core.Player.CurrentHealthPercent < GladiatorSettings.OathAutoHealthPercentage
                || GladiatorSettings.Oath == PallyOaths.Rotation && Spell.RotationSwap) && !Core.Player.HasAura("Shield Oath")))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Mercy Stroke", Core.Player.CurrentTarget, Core.Player.CurrentTarget != null && Core.Player.CurrentTarget.CurrentHealthPercent < 20))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Shield Bash", Core.Player.CurrentTarget, GladiatorSettings.ShieldBash))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }
            if (!Spell.UsedNoneGcd && await Spell.CastLock("Spirits Within", Core.Player.CurrentTarget, GladiatorSettings.SpiritsWithin))
            {
                Spell.UsedNoneGcd = true;
                return true;
            }

            return false;
        }

    }
}
